/*
 * Copyright (C) 2017 Baidu, Inc. All Rights Reserved.
 */
package com.xiaoq.baiduunit.parser;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.xiaoq.baiduunit.entity.CommunicateResponse;
import com.xiaoq.baiduunit.exception.UnitError;

import java.util.List;

public class CommunicateParser {

    public CommunicateResponse parse(String json) throws UnitError {
        try {
            JSONObject jsonObject = JSON.parseObject(json, Feature.AllowUnQuotedFieldNames,Feature.AllowArbitraryCommas);

            if (jsonObject.containsKey("error_code")) {
                UnitError error = new UnitError(jsonObject.getInteger("error_code"), jsonObject.getString("error_msg"));
                throw error;
            }

            CommunicateResponse result = new CommunicateResponse();
            result.setLogId(jsonObject.getLong("log_id"));
            result.setJsonRes(json);

            JSONObject resultObject = jsonObject.getJSONObject("result");
            List<CommunicateResponse.Action> actionList = result.actionList;
            JSONArray actionListArray = resultObject.getJSONArray("action_list");
            if (actionListArray != null) {
                for (int i = 0; i < actionListArray.size(); i++) {
                    JSONObject actionListObject = actionListArray.getJSONObject(i);
                    if (actionListObject == null) {
                        continue;
                    }
                    CommunicateResponse.Action action = new CommunicateResponse.Action();
                    action.actionId = actionListObject.getString("action_id");
                    JSONObject actionTypeObject = actionListObject.getJSONObject("action_type");

                    action.actionType = new CommunicateResponse.ActionType();
                    action.actionType.target = actionTypeObject.getString("act_target");
                    action.actionType.targetDetail = actionTypeObject.getString("act_target_detail");
                    action.actionType.type = actionTypeObject.getString("act_type");
                    action.actionType.typeDetail = actionTypeObject.getString("act_type_detail");

                    action.confidence = actionListObject.getInteger("confidence");
                    action.say = actionListObject.getString("say");

                    JSONArray hintListArray = actionListObject.getJSONArray("hint_list");
                    if (hintListArray != null) {
                        for (int j = 0; j < hintListArray.size(); j++) {
                            JSONObject hintQuery =  hintListArray.getJSONObject(j);
                            if (hintQuery != null) {
                                action.hintList.add(hintQuery.getString("hint_query"));
                            }
                        }
                    }

                    actionList.add(action);
                }
            }

            JSONObject quResObject = resultObject.getJSONObject("schema");
            if(quResObject != null){
                JSONArray botMergedSlotsArray = quResObject.getJSONArray("bot_merged_slots");

                if (botMergedSlotsArray != null) {
                    for (int j = 0; j < botMergedSlotsArray.size(); j++) {
                        JSONObject slotQuery =  botMergedSlotsArray.getJSONObject(j);
                        if (slotQuery != null) {
                            CommunicateResponse.Slots slots = new CommunicateResponse.Slots();
                            slots.setConfidence(slotQuery.getDouble("confidence"));
                            slots.setLength(slotQuery.getInteger("length"));
                            slots.setNeedClarify(slotQuery.getBoolean("need_clarify"));
                            slots.setNormalizedWord(slotQuery.getString("normalized_word"));
                            slots.setOffset(slotQuery.getInteger("offset"));
                            slots.setOriginalWord(slotQuery.getString("original_word"));
                            slots.setType(slotQuery.getString("type"));
                            slots.setWordType(slotQuery.getString("word_type"));
                            result.getSlots().add(slots);
                        }
                    }
                }
            }

            result.sessionId = resultObject.getString("session_id");

            return result;
        } catch (JSONException e) {
            e.printStackTrace();
            UnitError error = new UnitError(UnitError.ErrorCode.JSON_PARSE_ERROR, "Json parse error:" + json, e);
            throw error;
        }
    }
}
